#include "Sock.hpp"
#include "Server.hpp"
#include "Protocol.hpp"
#include "NetIO.hpp"
#include <memory>

namespace ns_calculator
{
#define SIZE 1024

    ns_protocol::Reponse caculatorHelp(int x, int y, char op)
    {
        ns_protocol::Reponse ret;
        switch (op)
        {
        case '+':
            ret._result = x + y;
            break;
        case '-':
            ret._result = x - y;
            break;
        case '*':
            ret._result = x * y;
            break;
        case '/':
            if (0 == y)
                ret._flag = 1;
            else
                ret._result = x / y;
            break;
        case '%':
            if (0 == y)
                ret._flag = 2;
            else
                ret._result = x % y;
            break;
        default:
            ret._flag = 3;
            break;
        }

        return ret;
    }

    // 计算函数
    void caculator(int sock)
    {
        std::string recv_buffer;
        while (true)
        {
            // ssize_t n = recv(sock, recv_buffer, SIZE - 1, 0);
            // if(n == 0)
            // {
            //     logMessage(ERROR, "Client close, Server close, too\n");
            //     break;
            // }
            // else if(n < 0)
            // {
            //     logMessage(ERROR, "recieve from client fail\n");
            //     continue;
            // }
            // logMessage(NORMAL, "Serve# recieve success\n");

            // 读取数据
            ns_protocol::Request req;
            while (true)
            {
                bool ret = ns_netio::Recv(sock, recv_buffer);
                if (!ret)
                    break;

                std::string deRecvMsg = ns_protocol::DeCode(recv_buffer);
                if(deRecvMsg.empty()) continue;

                // std::cout << 11111 << std::endl;

                // 反序列化
                req.deserialize(deRecvMsg);

                break;
            }

            // ns_protocol::Request req;

            // 计算
            // printf("req_x:%d req_op:%c req_y:%d\n", req._x, req._op, req._y);
            ns_protocol::Reponse rep = caculatorHelp(req._x, req._y, req._op);

            if (rep._flag == 0)
            {
                // printf("%d %c %d = %d\n", req._x, req._op, req._y, rep._result);
                std::cout << req._x << " " << req._op << " " << req._y << " = " << rep._result << std::endl;
            }
            else
            {
                logMessage(ERROR, "Something error, flag:%d\n", rep._result);
            }

            // 将数据发回到客户端
            std::string ans = rep.serialize();
            // std::cout << "序列化结果: " << ans << std::endl;
            ans = ns_protocol::EnCode(ans);

            bool ret = ns_netio::Send(sock, ans);
            if (!ret)
                break;
            // n = send(sock, ans.c_str(), ans.size(), 0);   // 数据发回客户端
            // if(n <= 0)
            // {
            //     logMessage(ERROR, "send back error\n");
            //     continue;
            // }
        }
    }
}

void Usage(const char *proc)
{
    std::cout << "\nServer Usage# " << proc << " serverPort\n"
              << std::endl;
}

int main(int argc, const char **argv)
{
    if (argc != 2)
    {
        Usage(argv[0]);
        exit(1);
    }
    MyDaemon();  
    std::unique_ptr<ns_tcpserver::Server> ptr_srv(new ns_tcpserver::Server(atoi(argv[1])));
    ptr_srv->BindServer(ns_calculator::caculator);
    ptr_srv->init();
    ptr_srv->start();

    return 0;
}